package org.ucas.faker.web.controller;

import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.ucas.faker.web.dto.PageDto;
import org.ucas.faker.web.dto.PatentDto;
import org.ucas.faker.web.fetcher.FetchReqBuilder;
import org.ucas.faker.web.fetcher.FetchResult;
import org.ucas.faker.web.service.PatentService;
import org.ucas.faker.web.utils.feature.BranchAndEffect;
import org.ucas.faker.web.utils.feature.FeatureGenTask;
import org.ucas.faker.web.utils.feature.FeatureGenerator;
import org.ucas.faker.web.utils.feature.TechGenerator;

import java.io.IOException;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * Created by suemi on 17-7-11.
 */
@RestController
public class PatentController extends BaseController {

  @Autowired
  private PatentService patentService;

  @Autowired
  private FeatureGenTask task;

  private static final List<FeatureGenerator> generators = new ArrayList<FeatureGenerator>(){{
    add(new TechGenerator());
  }};


  @RequestMapping(value = "/patents/selected" , method = RequestMethod.GET)
  public PageDto<PatentDto> selectedPatents(@RequestParam(value = "pageNum", required = false) Integer pageNum,
                                            @RequestParam(value = "pageSize", required = false) Integer pageSize,
                                            @RequestParam(value = "target", defaultValue = "1") Integer target) {

    pageNum = pageNum == null ? 0 : pageNum;
    pageSize = pageSize == null ? 500 : pageSize;

    return null; // TODO
  }
  
  //added for 技术特征功效矩阵
  public List<BranchAndEffect> branchAndEffects(long depotId) throws IllegalAccessException, InstantiationException {
//	  FetchReqBuilder builder = FetchReqBuilder.instance().select("id","branch","effect")
//        .selectAs("ab","abstraction").selectAs("pn","claim")
//        .depot(currentDepotId());
	  FetchReqBuilder builder = FetchReqBuilder.instance().select("id","br","pn","ab")
	            //.selectAs("ab","abstraction")
	            //.selectAs("pn","pn")
	            .depot(depotId);

	    FetchResult result = fetcher.fetch(builder.build());

	    List<Long> lid_initial = result.<Long>column("id");
	    List<String> lbr = result.<String>column("br");
	    //List<String> lef = result.<String>column("ef");
	    List<String> lab = result.<String>column("ab");
	    List<String> lpn = result.<String>column("pn");
	    List<Integer> lid = new ArrayList<>();
	    for(Long id:lid_initial){
	    	lid.add(id.intValue());
	    }
	    
	    HashMap<Integer,BranchAndEffect> map = new HashMap<>(); 
	    for(int i=0;i<lid.size();i++){
	    	//System.out.println(map.size());
	    	if(map.containsKey(lid.get(i))){
	    		//
	    		BranchAndEffect be = map.get(lid.get(i));
	    		be.setBranch(be.getBranch()+"#"+lbr.get(i));
	    		//System.out.println("PatentController,专利技术："+lbr.get(i));
	    		//be.setEffect(be.getEffect()+"#"+lef.get(i));
	    	}else{
	    		BranchAndEffect be = new BranchAndEffect();
	    		be.setAbstraction(lab.get(i));
	    		be.setId(lid.get(i));
	    		be.setClaim(lpn.get(i));
	    		be.setBranch(lbr.get(i));
	    		//System.out.println("PatentController,专利技术："+lbr.get(i));
	    		//be.setEffect("test effect");
	    		//be.setEffect(lef.get(i));
	    		map.put(lid.get(i), be);
	    	}
	    }
	    
	    

		  //组装effect
		  builder = FetchReqBuilder.instance().select("id","ef","pn","ab")
		            //.selectAs("ab","abstraction")
		            //.selectAs("pn","pn")
		            .depot(depotId);

		    result = fetcher.fetch(builder.build());

		    lid_initial = result.<Long>column("id");
		    List<String> lef = result.<String>column("ef");
		    lab = result.<String>column("ab");
		    lpn = result.<String>column("pn");
		    
		    lid.clear();
		    for(Long id:lid_initial){
		    	lid.add(id.intValue());
		    }
		    for(int i=0;i<lid.size();i++){
		    	//System.out.println(map.size());
		    	if(map.containsKey(lid.get(i))){
		    		//
		    		BranchAndEffect be = map.get(lid.get(i));
		    		if(be.getEffect()==null)
		    			be.setEffect(lef.get(i));
		    		else
		    			be.setEffect(be.getEffect()+"#"+lef.get(i));
		    		//System.out.println("PatentController,专利功效："+lef.get(i));
		    		//be.setEffect(be.getEffect()+"#"+lef.get(i));
		    	}else{
		    		BranchAndEffect be = new BranchAndEffect();
		    		be.setAbstraction(lab.get(i));
		    		be.setId(lid.get(i));
		    		be.setClaim(lpn.get(i));
		    		be.setEffect(lef.get(i));
		    		map.put(lid.get(i), be);
		    		//System.out.println("PatentController,专利功效："+lef.get(i));
		    	}
		    }
	    //System.out.println(map.size());
	    
//	    for(BranchAndEffect be:map.values()){
//	    	System.out.println(be.getBranch()+"  ::  "+be.getEffect());
//	    }
		    List<BranchAndEffect> res = new ArrayList<>();
		    for(BranchAndEffect be : map.values()){
		    	String tmp = be.getBranch();
		    	if(tmp.length()>0&&tmp.charAt(0)=='#')
		    		be.setBranch(tmp.substring(1));
		    	tmp = be.getEffect();
		    	if(tmp.length()>0 && tmp.charAt(0)=='#')
		    		be.setEffect(tmp.substring(1));
		    	res.add(be);
		    }
		    return res;
		    
		    
  }

  
  
  
  
  //feature and effect display lv
  private List<BranchAndEffect> branchAndEffects(Integer pageNumber, Integer pageSize, Long depotId) throws IllegalAccessException, InstantiationException {
//	  FetchReqBuilder builder = FetchReqBuilder.instance().select("id","branch","effect")
//        .selectAs("ab","abstraction").selectAs("pn","claim")
//        .depot(currentDepotId());
	  FetchReqBuilder builder = FetchReqBuilder.instance().select("id","br","pn","ab")
	            //.selectAs("ab","abstraction")
	            //.selectAs("pn","pn")
			    .depot(depotId);

	    FetchResult result = fetcher.fetch(builder.build());

	    List<Long> lid_initial = result.<Long>column("id");
	    List<String> lbr = result.<String>column("br");
	    //List<String> lef = result.<String>column("ef");
	    List<String> lab = result.<String>column("ab");
	    List<String> lpn = result.<String>column("pn");
	    List<Integer> lid = new ArrayList<>();
	    for(Long id:lid_initial){
	    	lid.add(id.intValue());
	    }
	    
	    HashMap<Integer,BranchAndEffect> map = new HashMap<>(); 
	    for(int i=0;i<lid.size();i++){
	    	//System.out.println(map.size());
	    	if(map.containsKey(lid.get(i))){
	    		//
	    		BranchAndEffect be = map.get(lid.get(i));
	    		be.setBranch(be.getBranch()+"#"+lbr.get(i));
	    		//be.setEffect(be.getEffect()+"#"+lef.get(i));
	    	}else{
	    		BranchAndEffect be = new BranchAndEffect();
	    		be.setAbstraction(lab.get(i));
	    		be.setId(lid.get(i));
	    		be.setClaim(lpn.get(i));
	    		be.setBranch(lbr.get(i));
	    		//be.setEffect(lef.get(i));
	    		//System.out.println(lab.get(i));
	    		map.put(lid.get(i), be);
	    	}
	    }
	    
	    

		  //组装effect
		  builder = FetchReqBuilder.instance().select("id","ef","pn","ab")
		            //.selectAs("ab","abstraction")
				  	.depot(depotId);

		    result = fetcher.fetch(builder.build());

		    lid_initial = result.<Long>column("id");
		    List<String> lef = result.<String>column("ef");
		    lab = result.<String>column("ab");
		    lpn = result.<String>column("pn");
		    
		    lid.clear();
		    for(Long id:lid_initial){
		    	lid.add(id.intValue());
		    }
		    for(int i=0;i<lid.size();i++){
		    	//System.out.println(map.size());
		    	if(map.containsKey(lid.get(i))){
		    		//
		    		BranchAndEffect be = map.get(lid.get(i));
		    		if(be.getEffect()==null)
		    			be.setEffect(lef.get(i));
		    		else
		    			be.setEffect(be.getEffect()+"#"+lef.get(i));
		    		//be.setEffect(be.getEffect()+"#"+lef.get(i));
		    	}else{
		    		BranchAndEffect be = new BranchAndEffect();
		    		be.setAbstraction(lab.get(i));
		    		be.setId(lid.get(i));
		    		be.setClaim(lpn.get(i));
		    		be.setEffect(lef.get(i));
		    		map.put(lid.get(i), be);
		    	}
		    }
	    //System.out.println(map.size());
	    
//	    for(BranchAndEffect be:map.values()){
//	    	System.out.println(be.getBranch()+"  ::  "+be.getEffect());
//	    }
		    List<BranchAndEffect> res = new ArrayList<>();
		    for(BranchAndEffect be : map.values()){
		    	String tmp = be.getBranch();
		    	if(tmp.length()>0&&tmp.charAt(0)=='#')
		    		be.setBranch(tmp.substring(1));
		    	tmp = be.getEffect();
		    	if(tmp.length()>0 && tmp.charAt(0)=='#')
		    		be.setEffect(tmp.substring(1));
		    	res.add(be);
		    }
		    return res;
  }
  //feature and effect display lv
  private List<BranchAndEffect> branchAndEffectsForDisplay(Long depotId) throws IllegalAccessException, InstantiationException {
		FetchReqBuilder builder = FetchReqBuilder.instance().select("id", "pn", "ab").depot(depotId);
		FetchResult result = fetcher.fetch(builder.build());
		List<Long> lid = result.<Long>column("id");
		// List<String> lef = result.<String>column("ef");
		List<String> lab = result.<String>column("ab");
		List<String> lpn = result.<String>column("pn");

		HashMap<Long, BranchAndEffect> map = new HashMap<>();
		//System.out.println("**********************::  "+lid.size());
		for(int i=0;i<lid.size();i++){
			if(!map.containsKey(lid.get(i).intValue())){
				BranchAndEffect be = new BranchAndEffect();
				be.setId(lid.get(i).intValue());
				be.setAbstraction(lab.get(i));
				be.setClaim(lpn.get(i));
				be.setBranch("");
				be.setEffect("");
				
				map.put(lid.get(i), be);
			}
			
		}
		
		
		//搜索并组装branch
		builder = FetchReqBuilder.instance().select("id", "br")
				.depot(depotId);
		result = fetcher.fetch(builder.build());
		
		lid = result.<Long>column("id");
		List<String> lbr = result.<String>column("br");
		
		for (int i = 0; i < lid.size(); i++) {
			if (map.containsKey(lid.get(i))) {
				BranchAndEffect be = map.get(lid.get(i));
				be.setBranch(be.getBranch() + "#" + lbr.get(i));
			}
		}

		// 搜索并组装effect
		builder = FetchReqBuilder.instance().select("id", "ef")
				.depot(depotId);
		result = fetcher.fetch(builder.build());

		lid = result.<Long>column("id");
		List<String> lef = result.<String>column("ef");

		for (int i = 0; i < lid.size(); i++) {
			// System.out.println(map.size());
			if (map.containsKey(lid.get(i))) {
				BranchAndEffect be = map.get(lid.get(i));
				be.setEffect(be.getEffect() + "#" + lef.get(i));
				// be.setEffect(be.getEffect()+"#"+lef.get(i));
			} 
		}
		
		
		for(BranchAndEffect be:map.values()){
			if(be.getBranch().length()>1) be.setBranch(be.getBranch().substring(1));
			if(be.getEffect().length()>1) be.setEffect(be.getEffect().substring(1));
			System.out.println(be.getId()+"\nBranch:"+be.getBranch()+"\nEffect:"+be.getEffect()+"\nAb:"+be.getAbstraction()+"\nPb:"+be.getClaim());
		}
		List<BranchAndEffect> res = new ArrayList<>();
		res.addAll(map.values());
		
		return res;
	}

	@RequestMapping(value = "/document/getTechEff", method = RequestMethod.GET)
	public PageDto<BranchAndEffect> getTechEff(
			@RequestParam(value = "searchQuery", required = false) String queryString,
			@RequestParam(value = "pageNumber", defaultValue = "1") Integer pageNumber,
			@RequestParam(value = "pageSize", defaultValue = "20") Integer pageSize,
			@RequestParam(value = "depotId", required = false) Long depotId) throws URISyntaxException, IOException,
			InvalidFormatException, InterruptedException, InstantiationException, IllegalAccessException {
		if (depotId == null)
			depotId = currentDepotId();
		List<BranchAndEffect> list = branchAndEffectsForDisplay(depotId);
		//
		// for(BranchAndEffect l:list){
		// System.out.println(l.getId()+"\n"+l.getAbstraction()+"\n"+l.getBranch()+"\n"+l.getEffect()+"\n");
		// }

		// List<PageDto<BranchAndEffect>> result = new
		// ArrayList<>();//PatentDto.of(tmpResult);
		return PageDto.ofList(list, list.size(), pageNumber, pageSize);
	}
}
